import os
import tempfile
from typing import Dict, Any
import logging

logger = logging.getLogger(__name__)

class PdfConverter:
    """PDF转换器"""
    
    def to_markdown(self, pdf_path: str, options: Dict[str, Any] = None) -> str:
        """
        将PDF转换为Markdown
        
        Args:
            pdf_path: PDF文件路径
            options: 转换选项
            
        Returns:
            Markdown内容
        """
        if not options:
            options = {}
        
        try:
            # 尝试使用PyMuPDF (fitz)
            import fitz
            return self._extract_with_pymupdf(pdf_path, options)
        except ImportError:
            try:
                # 尝试使用pdfplumber
                import pdfplumber
                return self._extract_with_pdfplumber(pdf_path, options)
            except ImportError:
                try:
                    # 尝试使用PyPDF2
                    import PyPDF2
                    return self._extract_with_pypdf2(pdf_path, options)
                except ImportError:
                    raise Exception("需要安装PyMuPDF、pdfplumber或PyPDF2库来支持PDF文本提取")
    
    def _extract_with_pymupdf(self, pdf_path: str, options: Dict[str, Any]) -> str:
        """使用PyMuPDF提取PDF文本"""
        import fitz
        
        doc = fitz.open(pdf_path)
        content = []
        
        # 添加文件名作为标题（如果选项中指定）
        if options.get('add_title', False):
            filename = os.path.splitext(os.path.basename(pdf_path))[0]
            content.append(f'# {filename}')
            content.append('')
        
        for page_num in range(len(doc)):
            page = doc.load_page(page_num)
            
            # 提取文本
            text = page.get_text()
            
            if text.strip():
                # 处理页面文本
                processed_text = self._process_extracted_text(text, options)
                if processed_text:
                    content.append(processed_text)
                    content.append('')
            
            # 如果需要，添加页面分隔符
            if options.get('add_page_breaks', False) and page_num < len(doc) - 1:
                content.append('---')
                content.append('')
        
        doc.close()
        return '\n'.join(content)
    
    def _extract_with_pdfplumber(self, pdf_path: str, options: Dict[str, Any]) -> str:
        """使用pdfplumber提取PDF文本"""
        import pdfplumber
        
        content = []
        
        # 添加文件名作为标题（如果选项中指定）
        if options.get('add_title', False):
            filename = os.path.splitext(os.path.basename(pdf_path))[0]
            content.append(f'# {filename}')
            content.append('')
        
        with pdfplumber.open(pdf_path) as pdf:
            for page_num, page in enumerate(pdf.pages):
                # 提取文本
                text = page.extract_text()
                
                if text and text.strip():
                    # 处理页面文本
                    processed_text = self._process_extracted_text(text, options)
                    if processed_text:
                        content.append(processed_text)
                        content.append('')
                
                # 提取表格
                tables = page.extract_tables()
                for table in tables:
                    if table:
                        table_md = self._convert_table_to_markdown(table)
                        if table_md:
                            content.extend(table_md)
                            content.append('')
                
                # 如果需要，添加页面分隔符
                if options.get('add_page_breaks', False) and page_num < len(pdf.pages) - 1:
                    content.append('---')
                    content.append('')
        
        return '\n'.join(content)
    
    def _extract_with_pypdf2(self, pdf_path: str, options: Dict[str, Any]) -> str:
        """使用PyPDF2提取PDF文本"""
        import PyPDF2
        
        content = []
        
        # 添加文件名作为标题（如果选项中指定）
        if options.get('add_title', False):
            filename = os.path.splitext(os.path.basename(pdf_path))[0]
            content.append(f'# {filename}')
            content.append('')
        
        with open(pdf_path, 'rb') as file:
            pdf_reader = PyPDF2.PdfReader(file)
            
            for page_num, page in enumerate(pdf_reader.pages):
                # 提取文本
                text = page.extract_text()
                
                if text and text.strip():
                    # 处理页面文本
                    processed_text = self._process_extracted_text(text, options)
                    if processed_text:
                        content.append(processed_text)
                        content.append('')
                
                # 如果需要，添加页面分隔符
                if options.get('add_page_breaks', False) and page_num < len(pdf_reader.pages) - 1:
                    content.append('---')
                    content.append('')
        
        return '\n'.join(content)
    
    def _process_extracted_text(self, text: str, options: Dict[str, Any]) -> str:
        """处理提取的文本"""
        if not text or not text.strip():
            return ""
        
        lines = text.split('\n')
        processed_lines = []
        
        for line in lines:
            line = line.strip()
            if not line:
                continue
            
            # 尝试识别标题（简单的启发式方法）
            if self._is_likely_heading(line, options):
                # 根据文本特征判断标题级别
                level = self._guess_heading_level(line)
                processed_lines.append('#' * level + ' ' + line)
            else:
                processed_lines.append(line)
        
        return '\n\n'.join(processed_lines)
    
    def _is_likely_heading(self, line: str, options: Dict[str, Any]) -> bool:
        """判断是否可能是标题"""
        # 简单的启发式规则
        if len(line) > 100:  # 太长的行不太可能是标题
            return False
        
        # 如果行全部是大写字母，可能是标题
        if line.isupper() and len(line.split()) <= 10:
            return True
        
        # 如果行以数字开头（如 "1. 章节标题"），可能是标题
        if line[0].isdigit() and '. ' in line[:10]:
            return True
        
        # 如果行很短且不以标点符号结尾，可能是标题
        if len(line) < 50 and not line.endswith(('.', '!', '?', ':', ';')):
            return True
        
        return False
    
    def _guess_heading_level(self, line: str) -> int:
        """猜测标题级别"""
        # 简单的启发式方法
        if line.isupper():
            return 1  # 全大写可能是一级标题
        elif line[0].isdigit():
            return 2  # 数字开头可能是二级标题
        else:
            return 3  # 其他情况默认为三级标题
    
    def _convert_table_to_markdown(self, table) -> list:
        """将表格转换为Markdown格式"""
        if not table or len(table) < 2:
            return []
        
        markdown_table = []
        
        # 处理表头
        headers = [str(cell) if cell else '' for cell in table[0]]
        markdown_table.append('| ' + ' | '.join(headers) + ' |')
        markdown_table.append('| ' + ' | '.join(['---'] * len(headers)) + ' |')
        
        # 处理数据行
        for row in table[1:]:
            cells = [str(cell) if cell else '' for cell in row]
            # 确保单元格数量与表头一致
            while len(cells) < len(headers):
                cells.append('')
            markdown_table.append('| ' + ' | '.join(cells[:len(headers)]) + ' |')
        
        return markdown_table
    
    def to_docx(self, pdf_path: str, output_path: str, options: Dict[str, Any] = None):
        """
        将PDF转换为Word文档（通过Markdown中间格式）
        
        Args:
            pdf_path: PDF文件路径
            output_path: 输出Word文档路径
            options: 转换选项
        """
        # 先转换为Markdown
        markdown_content = self.to_markdown(pdf_path, options)
        
        # 再转换为Word
        from .markdown_converter import MarkdownConverter
        md_converter = MarkdownConverter()
        md_converter.to_docx(markdown_content, output_path, options) 